﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Comm.PublicClass;

namespace Wasion.HHU.Services
{
    public class TCommProperty  //各表位通信参数类
    {
        public int SNO { get; set; }  //表位号
        public string CommName { get; set; }  //串口号
        public SourceMeterMode ConnMode { get; set; }  //通信方式
        public WSFunctionType wsFunction { get; set; }  //多功能板类别
        public int BaudRate { get; set; }  //波特率
        public int HandshakeBaudRate { get; set; }  //握手波特率
        public int Databit { get; set; }  //数据位
        public int HandDatabit { get; set; }  //握手数据位
        //public Parity Parity { get; set; }  //校验方式

        public static int ByteDelay { get; set; } //字节间延时        
        public static int OrderDelay { get; set; } //指令间延时        
        public static int ByteOvertime { get; set; } //字节间超时        
        public static int OrderWait { get; set; } //指令超时        
        public static int OrderLoad { get; set; } //返回帧缓冲延时                
        public static int RedoTimes { get; set; } //重读次数           
        public static string WakeChar { get; set; } //前导符        
        public static string DelayChar { get; set; } //后导符

        private const char splitchar = ',';
        private static Dictionary<int, TCommProperty> CommLst = null;
        public static int MaxMeter = 0;  //最大表位数

        public TCommProperty()
        {
            CommName = string.Empty;
            ConnMode = SourceMeterMode.串口485;
            wsFunction = WSFunctionType.无多功能板;
            BaudRate = 2400;
            HandshakeBaudRate = 300;
            Databit = 8;
            HandDatabit = 8;
            //Parity = Parity.Even;
        }

        /// <summary>
        /// 获取各表位通信参数
        /// </summary>
        public static Dictionary<int, TCommProperty> GetCommProperty(ref string errinfo)
        {
            ByteOvertime = 130;
            OrderWait = 5;
            RedoTimes = 1;
            WakeChar = string.Empty;
            DelayChar = string.Empty;
            if (CommLst == null)
                CommLst = new Dictionary<int, TCommProperty>();
            else
                CommLst.Clear();

            //string inifilename = AppDomain.CurrentDomain.BaseDirectory + PtlBaseUIProConsts.iniFileName;
            string[] Commlist, BaudRatelist, HandBaudRatelst, Databitlist, HandDatabitlist, Paritylist, Modelist, FunctionList;

            ////串口号
            //string temp = RWOutFiles.GetINIString(inifilename, "COM", "CommName", "COM1");
            //Commlist = temp.ToString().Split(splitchar);

            ////波特率
            //temp = RWOutFiles.GetINIString(inifilename, "COM", "BaudRate", "2400");
            //BaudRatelist = temp.ToString().Split(splitchar);

            ////握手波特率
            //temp = RWOutFiles.GetINIString(inifilename, "COM", "HandBaudRate", "300");
            //HandBaudRatelst = temp.ToString().Split(splitchar);
            

            ////数据位
            //temp = RWOutFiles.GetINIString(inifilename, "COM", "Databit", "8");
            //Databitlist = temp.ToString().Split(splitchar);


            ////握手数据位
            //temp = RWOutFiles.GetINIString(inifilename, "COM", "HandDatabit", "8");
            //HandDatabitlist = temp.ToString().Split(splitchar);

            ////校验方式
            //temp = RWOutFiles.GetINIString(inifilename, "COM", "Parity", "2");
            //Paritylist = temp.ToString().Split(splitchar);

            ////通信方式
            //temp = RWOutFiles.GetINIString(inifilename, "COM", "ConnMode", "");
            //Modelist = temp.ToString().Split(splitchar);

            ////多功能板类别
            //temp = RWOutFiles.GetINIString(inifilename, "COM", "WSFunction", "");
            //FunctionList = temp.ToString().Split(splitchar);

            ////字节间延时
            //temp = RWOutFiles.GetINIString(inifilename, "Delay", "ByteDelay", "0");
            //try
            //{
            //    ByteDelay = Int16.Parse(temp);
            //}
            //catch (Exception e)
            //{
            //    errinfo = "字节间延时非法:" + e.Message;
            //}

            ////指令间延时
            //temp = RWOutFiles.GetINIString(inifilename, "Delay", "OrderDelay", "0");
            //try
            //{
            //    OrderDelay = Int16.Parse(temp);
            //}
            //catch (Exception e)
            //{
            //    errinfo = "指令间延时非法:" + e.Message;
            //}

            ////字节间超时
            //temp = RWOutFiles.GetINIString(inifilename, "Delay", "ByteOvertime", "120");
            //try
            //{
            //    ByteOvertime = Int16.Parse(temp);
            //}
            //catch (Exception e)
            //{
            //    errinfo = "字节间超时非法:" + e.Message;
            //}

            ////指令超时
            //temp = RWOutFiles.GetINIString(inifilename, "Delay", "OrderWait", "0");
            //try
            //{
            //    OrderWait = Int16.Parse(temp);
            //}
            //catch (Exception e)
            //{
            //    errinfo = "指令超时非法:" + e.Message;
            //}

            ////返回帧缓冲延时
            //temp = RWOutFiles.GetINIString(inifilename, "Delay", "OrderLoad", "0");
            //try
            //{
            //    OrderLoad = Int16.Parse(temp);
            //}
            //catch (Exception e)
            //{
            //    errinfo = "返回帧缓冲延时非法:" + e.Message;
            //}

            ////最多执行次数            
            //temp = RWOutFiles.GetINIString(inifilename, "Delay", "RedoTimes", "0");
            //try
            //{
            //    RedoTimes = Int16.Parse(temp);
            //}
            //catch (Exception e)
            //{
            //    errinfo = "最多执行次数非法:" + e.Message;
            //}

            ////前导符
            //WakeChar = RWOutFiles.GetINIString(inifilename, "Delay", "WakeChar", "");

            ////后导符
            //DelayChar = RWOutFiles.GetINIString(inifilename, "Delay", "DelayChar", "");


            //for (int j = 0; j < Commlist.Length; j++)
            //{
            //    TCommProperty commproperty = new TCommProperty();
            //    commproperty.SNO = j + 1;
            //    commproperty.CommName = string.IsNullOrEmpty(Commlist[j]) ? "无" : Commlist[j];
            //    if (j < Paritylist.Length)
            //        commproperty.Parity = (Parity)Int16.Parse(Paritylist[j]);
            //    if (j < BaudRatelist.Length)
            //        commproperty.BaudRate = Int32.Parse(BaudRatelist[j]);

            //    if (j < HandBaudRatelst.Length)
            //        commproperty.HandshakeBaudRate = Int32.Parse(HandBaudRatelst[j]);

            //    if (j < Databitlist.Length)
            //        commproperty.Databit = Int32.Parse(Databitlist[j]);

            //    if (j < HandDatabitlist.Length)
            //        commproperty.HandDatabit = Int32.Parse(HandDatabitlist[j]);

            //    try
            //    {
            //        commproperty.ConnMode = (SourceMeterMode)Convert.ToInt16(Modelist[j]);
            //    }
            //    catch
            //    {
            //        commproperty.ConnMode = SourceMeterMode.串口485;
            //    }

            //    try
            //    {
            //        commproperty.wsFunction = (WSFunctionType)Convert.ToInt16(FunctionList[j]);
            //    }
            //    catch
            //    {
            //        commproperty.wsFunction = 0;
            //    }
            //    CommLst.Add(commproperty.SNO, commproperty);

            //}

            return CommLst;
        }

        /// <summary>
        /// 保存各表位通信参数
        /// </summary>
        /// <param name="errinfo"></param>
        /// <returns></returns>
        public static int SaveCommProperty(ref string errinfo)
        {
            int rs = 0;
            try
            {
                //string inifilename = AppDomain.CurrentDomain.BaseDirectory + PtlBaseUIProConsts.iniFileName;

                //字节间延时
                //RWOutFiles.WriteINIString(inifilename, "Delay", "ByteDelay", Convert.ToString(ByteDelay));

                ////字节间超时
                //RWOutFiles.WriteINIString(inifilename, "Delay", "ByteOvertime", Convert.ToString(ByteOvertime));

                ////指令间延时
                //RWOutFiles.WriteINIString(inifilename, "Delay", "OrderDelay", Convert.ToString(OrderDelay));


                ////指令超时
                //RWOutFiles.WriteINIString(inifilename, "Delay", "OrderWait", Convert.ToString(OrderWait));

                ////重读次数            
                //RWOutFiles.WriteINIString(inifilename, "Delay", "RedoTimes", Convert.ToString(RedoTimes));

                ////前导符
                //RWOutFiles.WriteINIString(inifilename, "Delay", "WakeChar", WakeChar);

                ////后导符
                //RWOutFiles.WriteINIString(inifilename, "Delay", "DelayChar", DelayChar);


                string Commlist = string.Empty;
                string BaudRatelist = string.Empty;
                string HandBaudRatelst = string.Empty;
                string Databitlist = string.Empty;
                string HandDatabitlst = string.Empty;
                string Paritylist = string.Empty;
                string Modelist = string.Empty;
                string Functionlist = string.Empty;
                for (int sno = 1; sno <= CommLst.Count; sno++)
                {
                    if (MaxMeter > 0 && sno > MaxMeter)
                        break;
                    TCommProperty commproperty = CommLst[sno];
                    if (commproperty.ConnMode == SourceMeterMode.串口485 || commproperty.ConnMode == SourceMeterMode.光口通信)
                    {
                        if (commproperty.CommName.ToUpper().IndexOf("COM") < 0)
                        {
                            errinfo = "串口号配置有误";
                            return -1;
                        }
                    }
                    
                    Commlist += commproperty.CommName;
                    BaudRatelist += Convert.ToString(commproperty.BaudRate);
                    HandBaudRatelst += Convert.ToString(commproperty.HandshakeBaudRate);
                    Databitlist += Convert.ToString(commproperty.Databit);
                    HandDatabitlst += Convert.ToString(commproperty.HandDatabit);
                    //Paritylist += Convert.ToString((int)commproperty.Parity);
                    Modelist += Convert.ToString((int)commproperty.ConnMode);
                    Functionlist += Convert.ToString((int)commproperty.wsFunction);

                    if (sno < CommLst.Count)
                    {
                        Commlist += splitchar;
                        BaudRatelist += splitchar;
                        HandBaudRatelst += splitchar;
                        Databitlist += splitchar;
                        HandDatabitlst += splitchar;
                        Paritylist += splitchar;
                        Modelist += splitchar;
                        Functionlist += splitchar;
                    }

                }
                if (Commlist.EndsWith(splitchar.ToString()))
                    Commlist = Commlist.Substring(0, Commlist.Length - 1);
                if (BaudRatelist.EndsWith(splitchar.ToString()))
                    BaudRatelist = BaudRatelist.Substring(0, BaudRatelist.Length - 1);
                if (HandBaudRatelst.EndsWith(splitchar.ToString()))
                    HandBaudRatelst = HandBaudRatelst.Substring(0, HandBaudRatelst.Length - 1);
                if (Databitlist.EndsWith(splitchar.ToString()))
                    Databitlist = Databitlist.Substring(0, Databitlist.Length - 1);
                if (HandDatabitlst.EndsWith(splitchar.ToString()))
                    HandDatabitlst = HandDatabitlst.Substring(0, HandDatabitlst.Length - 1);
                if (Paritylist.EndsWith(splitchar.ToString()))
                    Paritylist = Paritylist.Substring(0, Paritylist.Length - 1);
                if (Modelist.EndsWith(splitchar.ToString()))
                    Modelist = Modelist.Substring(0, Modelist.Length - 1);
                if (Functionlist.EndsWith(splitchar.ToString()))
                    Functionlist = Functionlist.Substring(0, Functionlist.Length - 1);


                //串口号
                //RWOutFiles.WriteINIString(inifilename, "COM", "CommName", Commlist);

                ////波特率
                //RWOutFiles.WriteINIString(inifilename, "COM", "BaudRate", BaudRatelist);

                ////握手波特率
                //RWOutFiles.WriteINIString(inifilename, "COM", "HandBaudRate", HandBaudRatelst);

                ////数据位
                //RWOutFiles.WriteINIString(inifilename, "COM", "Databit", Databitlist);

                ////握手数据位
                //RWOutFiles.WriteINIString(inifilename, "COM", "HandDatabit", HandDatabitlst);

                ////校验方式
                //RWOutFiles.WriteINIString(inifilename, "COM", "Parity", Paritylist);

                ////通信方式
                //RWOutFiles.WriteINIString(inifilename, "COM", "ConnMode", Modelist);

                ////多功能板类别
                //RWOutFiles.WriteINIString(inifilename, "COM", "WSFunction", Functionlist);



                rs = 1;
            }
            catch (Exception e)
            {
                errinfo = "保存通信参数失败:" + e.Message;
                rs = -1;
            }
            return rs;
        }


        /// <summary>
        /// 保存某表位的波特率
        /// </summary>
        /// <param name="ameter"></param>
        //public void SaveBaudRate(int sno, int newBaudRate)
        //{
        //    //保存至配置文件
        //    string inifilename = AppDomain.CurrentDomain.BaseDirectory + PtlBaseUIProConsts.iniFileName;
        //    string[] BaudRatelist = RWOutFiles.GetINIString(inifilename, "COM", "BaudRate", "2400").Split(',');

        //    if (sno <= BaudRatelist.Length)
        //        BaudRatelist[sno - 1] = Convert.ToString(newBaudRate);
        //    string baudstr = string.Empty;
        //    for (int i = 0; i < BaudRatelist.Length; i++)
        //    {
        //        baudstr += BaudRatelist[i];
        //        if (i < BaudRatelist.Length - 1)
        //            baudstr += ",";
        //    }
        //    RWOutFiles.WriteINIString(inifilename, "COM", "BaudRate", baudstr);
        //}


        /// <summary>
        /// 获取某个表位的通信参数
        /// </summary>
        /// <param name="SNO">表位</param>
        /// <returns></returns>
        public static TCommProperty GetCommProperty(int SNO, ref string errinfo)
        {
            if (CommLst == null)
                GetCommProperty(ref errinfo);

            if (CommLst.ContainsKey(SNO))
                return CommLst[SNO];
            else
                return null;
        }

        /// <summary>
        /// 添加通信参数对象 
        /// </summary>
        /// <param name="SNO"></param>
        /// <param name="aCommProperty"></param>
        public static void AddCommProperty(TCommProperty aCommProperty)
        {
            if (CommLst == null)
            {
                string errinfo = string.Empty;
                GetCommProperty(ref errinfo);
            }
            int sno = aCommProperty.SNO;
            if (CommLst.ContainsKey(sno))
                CommLst[sno] = aCommProperty;
            else
                CommLst.Add(sno, aCommProperty);
        }


        /// <summary>
        /// 上层通信方式转为底层通信方式
        /// </summary>
        /// <param name="connmode"></param>
        public static int SetConnMode(CommConst.TOrdertype aorder)
        {
            int rs = 1;
            string errinfo = string.Empty;
            //TCommProperty commpro = TCommProperty.GetCommProperty(aorder.MeterSNo, ref errinfo);
            TCommProperty commpro = new TCommProperty();
            commpro.ConnMode = SourceMeterMode.串口485;
            if (commpro == null)
            {
                aorder.errorinfo = errinfo;
                return -1;
            }

            switch (commpro.ConnMode)
            {
                case SourceMeterMode.TCP直连:
                    aorder.connMode = CommMode.TCPC;
                    break;
                case SourceMeterMode.UDP直连:
                    aorder.connMode = CommMode.UDPC;
                    break;
                case SourceMeterMode.串口485:
                    aorder.connMode = CommMode.RS232;
                    aorder.commname = commpro.CommName;
                    break;
                case SourceMeterMode.光口通信:
                    aorder.connMode = CommMode.OPTICAL;
                    if (aorder.ptltype == (int)PtlType.IEC1107)
                        aorder.connMode = CommMode.OPTICAL1107;
                    aorder.commname = commpro.CommName;
                    break;
                //case SourceMeterMode.低功耗蓝牙:
                //    aorder.connMode = Comm.BottomComm.CommProperty.CommMode.BLELOW;
                //    aorder.commname = commpro.CommName;
                //    break;
                case SourceMeterMode.威胜蓝牙:
                    aorder.connMode = CommMode.WSBLE;
                    aorder.commname = commpro.CommName;
                    break;
                case SourceMeterMode.台体485:
                case SourceMeterMode.台体红外:
                    //这里不管通信参数，直接把指令扔给硬件处理类
                    break;
            }
            return rs;
        }
    }

    public enum WSFunctionType
    {
        无多功能板 = 0,
        Auto645多功能板 = 1
    }
}
